package water_ruler_threads;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zhejiangzhengyuan.municipal_common.entity.*;
import com.zhejiangzhengyuan.municipal_common.entity.vo.DeviceMonitorValueVo;
import com.zhejiangzhengyuan.municipal_common.service.*;
import com.zhejiangzhengyuan.municipal_common.utils.ConstantUtil;
import com.zhejiangzhengyuan.municipal_common.utils.LED.DeviceUtils;
import com.zhejiangzhengyuan.municipal_common.utils.LED.URLUtils;
import com.zhejiangzhengyuan.municipal_common.utils.waterRuler.DataUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;

import java.io.IOException;
import java.net.Socket;
import java.sql.Timestamp;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import static com.zhejiangzhengyuan.municipal_common.utils.DateFormatUtil.timeFormat;

@Slf4j
public class ReceiveThread implements Runnable {
  private String deviceType = ConstantUtil.DEVICE_TYPE.FLOODED_ROAD;
  private String moduleName = ConstantUtil.MODULE_NAME.FLOODED_ROAD;
  private String warnType = ConstantUtil.WARN_TYPE.FLOODED_ROAD;
  private DeviceService deviceService;
  private DeviceMonitorValueService deviceMonitorValueService;
  private DeviceDataService deviceDataService;
  private WarnEventService warnEventService;
  private ElectronicDataService electronicDataService;
  // led 数据库连接
  private LedBindingService ledBindingService;
  private LedHistoryService ledHistoryService;
  private URLUtils urlUtils;
  private String data;

  private Socket socket;

  public ReceiveThread(
      Socket socket,
      String allData,
      DeviceService deviceService,
      DeviceMonitorValueService deviceMonitorValueService,
      DeviceDataService deviceDataService,
      WarnEventService warnEventService,
      ElectronicDataService electronicDataService,
      LedBindingService ledBindingService,
      LedHistoryService ledHistoryService,
      URLUtils urlUtils) {
    this.socket = socket;
    this.data = allData;
    this.deviceService = deviceService;
    this.deviceMonitorValueService = deviceMonitorValueService;
    this.deviceDataService = deviceDataService;
    this.warnEventService = warnEventService;
    this.electronicDataService = electronicDataService;
    this.ledBindingService = ledBindingService;
    this.ledHistoryService = ledHistoryService;
    this.urlUtils = urlUtils;
  }

  public void run() {
    if (data != null) {
      JSONObject map = DataUtils.GetListenerData(data);
      log.info("客户端地址和端口为：{}", socket.getRemoteSocketAddress());
      Timestamp timestamp = timeFormat(System.currentTimeMillis());
      Integer waterLevel = map.getInteger("WaterLevel");
      log.info(waterLevel + "");
      // 水尺距离地面200cm
      Integer maxLevel = 197;
      waterLevel = maxLevel - waterLevel;
      String phone = map.getString("Phone");
      log.info(phone);
      // 根据手机号码找设备，水位 197cm
      // 根据类型和手机号码找到设备
      QueryWrapper<Device> deviceQueryWrapper = new QueryWrapper<>();
      deviceQueryWrapper.eq("type", deviceType).eq("code", phone).like("name", "水尺");
      Device device = deviceService.getOne(deviceQueryWrapper);
      // 根据设备找到对应设置的阈值
      QueryWrapper<DeviceMonitorValue> deviceMonitorValueQueryWrapper = new QueryWrapper<>();
      deviceMonitorValueQueryWrapper.eq("module_type", moduleName);
      List<DeviceMonitorValue> list =
          deviceMonitorValueService.list(deviceMonitorValueQueryWrapper);
      if (Objects.isNull(device) || Objects.isNull(list) || list.isEmpty()) {
        return;
      }
      // 存储检测值
      ElectronicData electronicData = new ElectronicData();
      electronicData
          .setCheckName("水位")
          .setCreateTime(timestamp)
          .setValueUnit("cm")
          .setDeviceCode(device.getCode())
          .setMonPointName(device.getGeomDes())
          .setValue(waterLevel);
      electronicDataService.save(electronicData);
      // 记录接收值
      DeviceData data =
          new DeviceData()
              .setCreateTime(timestamp)
              .setDeviceId(device.getId())
              .setDeviceType(deviceType)
              .setOriginValue(map.toJSONString());
      deviceDataService.save(data);
      DeviceMonitorValueVo deviceMonitorValueVo = DeviceMonitorValueVo.formatVo(list);
      QueryWrapper<WarnEvent> warnEventQueryWrapper = new QueryWrapper<>();
      // 若告警事件形成案件则不作处理，未形成案件 更新告警事件状态
      warnEventQueryWrapper
          .eq("device_id", device.getId())
          .eq("type", warnType)
          .eq("reset", false)
          .eq("send_order", false);
      WarnEvent warnEvent = warnEventService.getOne(warnEventQueryWrapper);
      String grade = null;
      if (waterLevel >= deviceMonitorValueVo.getWarnValue3()) {
        grade = "三级";
        // 发送led信息
        // 获取ledMAC；
        QueryWrapper<LedBinding> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("ruler_code", phone);
        List<LedBinding> ledList = ledBindingService.list(queryWrapper);
        if (Objects.nonNull(ledList) && !ledList.isEmpty()) {
          for (LedBinding ledBinding : ledList) {
            String mac = ledBinding.getLedCode();
            Document document = null;
            try {
              document = Jsoup.connect(urlUtils.GetDeviceMainURL()).get();
            } catch (IOException e) {
              continue;
            }
            List<Map<String, String>> mapList = DeviceUtils.GetDeviceData(document);
            if (Objects.nonNull(mapList) && !mapList.isEmpty()) {
              for (Map<String, String> map1 : mapList) {
                if (map1.get("MAC").equals(mac)) {
                  // 发送LED消息
                  ledHistoryService.sendLedData(
                      map1.get("DeviceCode"), mac,"水位当前深度:" + waterLevel + "cm,禁止通行");
                }
              }
            }
          }
        }

      } else if (waterLevel >= deviceMonitorValueVo.getWarnValue2()) {
        grade = "二级";
      } else if (waterLevel >= deviceMonitorValueVo.getWarnValue1()) {
        grade = "一级";
      }
      if (Strings.isNotBlank(grade)) {
        formatWarnMessage(warnEvent, grade, device.getId(), waterLevel, timestamp);
      }
    }
  }

  private void formatWarnMessage(
      WarnEvent warnEvent, String level, Long deviceId, Integer waterLevel, Timestamp timestamp) {
    if (Objects.isNull(warnEvent)) {
      warnEvent =
          new WarnEvent()
              .setReason("水位异常,积水高度:" + waterLevel + "厘米")
              .setReportUserInfoId(1L)
              .setCreateTime(timestamp)
              .setUpdateTime(timestamp)
              .setLevel(level)
              .setDataOrigin(ConstantUtil.WARN_DATA_ORIGIN.SYSTEM)
              .setDeviceId(deviceId);
      warnEventService.insertWarnEvent(moduleName, warnEvent, warnType, "监控中心");
    } else if (!warnEvent.getLevel().equals(level)) {
      // 修改等级需要重新推送信息
      warnEvent
          .setLevel(level)
          .setReason("水位异常,积水高度:" + waterLevel + "厘米")
          .setUpdateTime(timestamp);
      warnEventService.updateWarnEvent(moduleName, warnEvent, warnType, "监控中心");
    } else {
      // 只修改告警事件本身
      warnEvent.setReason("水位异常,积水高度:" + waterLevel + "厘米").setUpdateTime(timestamp);
      warnEventService.updateById(warnEvent);
    }
  }
}
